package Logik;

import Interfaces.Kundenverwaltung;
import java.util.ArrayList;
import java.util.List;
import java.io.*;
import GUI.*;

/**
 * Implementiert das Interface und beinhaltet zwei weitere Methoden zum Laden
 * und zum Speichern der Kundenliste. Öffnet mit ObjectInputStream die Liste aus
 * der Datei und schreibt diese in die Kundenliste. Gibt ein Fehlerfenster aus,
 * wenn die Kundennummer schon vergeben ist. Schreibt mit ObjectOutputStream die
 * Kundenliste in die Datei.
 *
 * @author Tobias Graspointner
 *
 * @param kl - Kundenliste
 * @param kdata - Kundendatei mit Kundenliste
 *
 */
public class Kundenquelle implements Kundenverwaltung, Serializable {

    private List<Kunde> kl = new ArrayList<Kunde>();
    File kdata = new File("src/Logik/Kundenliste.data");

    @Override
    public void anlegen(Kunde k) {

        laden();

        if (kl.contains(k.getkundennr())) {
            Fehler_Kunde window = new Fehler_Kunde();
            window.setVisible(true);
        } else {
            kl.add(k);
        }

        speichern();
    }

    /**
     * Sucht das übergebene Kundenobjekt in der Kundenliste und löscht dieses.
     * Öffnet mit ObjectInputStream die Liste aus der Datei und schreibt diese
     * in die Kundenliste. Wenn die Kundennummer des übergebenen Kunden in der
     * Kundenliste gefunden wird, wird diese gelöscht. Schreibt mit
     * ObjectOutputStream die Kundenliste in die Datei.
     *
     * @param k - Kunde
     * @param kl - Kundenliste
     */
    @Override
    public void loeschen(int kundenNummer){

        laden();
        
        for (Kunde k : kl) {
            if (k.getkundennr() == kundenNummer) {
                kl.remove(k);
                speichern();
                return;

            }
        }
        speichern();
}
    /**
     * Sucht in der vorhandenen Kundenliste nach der übgergebenen Kundennummer
     * und schreibt die Ergebnisse in eine neue Liste. Öffnet mit
     * ObjectInputStream die Liste aus der Datei und schreibt diese in die
     * Kundenliste. Gibt ein Fehlerfenster aus, wenn die Liste, in der gesucht
     * wird leer ist. Schreibt das Kundenobjekt mit der gesuchten Kundennummer
     * in eine neue Liste.
     *
     * @param knr - übergebene Kundennummer, nach der gesucht wird.
     * @param kl - Kundenliste
     * @return ges - Liste, die gesuchte Objekte enthält.
     */
    @Override
    public List suchen(int knr) {

        List<Kunde> ges = new ArrayList<Kunde>();

        laden();

        if (kl.isEmpty() == true) {
            Fehler_kListe window = new Fehler_kListe();
            window.setVisible(true);

        } else if (kl.contains(knr)) {
            for (int i = 0; i < kl.size(); i++) {
                if (kl.get(i).getkundennr() == knr) {
                    ges.add(kl.get(kl.indexOf(i)));
                }
            }
        }
        return ges;
    }

    /**
     * Durchsucht die vorhandene Kundenliste nach dem übergebenen Kundenobjekt
     * und überschreibt dieses mit den übergebenen Kundenattributen. Öffnet mit
     * ObjectInputStream die Liste aus der Datei und schreibt diese in die
     * Kundenliste. Gibt ein Fehlerfenster aus, wenn die Liste, in der gesucht
     * wird leer ist. Überschreibt das Kundenobjekt mit dem übergebenen
     * Kundenobjekt. Schreibt mit ObjectOutputStream die Kundenliste in die
     * Datei.
     *
     * @param k
     */
    @Override
    public void aendern(Kunde k) {

        laden();

        if (kl.isEmpty() == true) {
            Fehler_kListe window = new Fehler_kListe();
            window.setVisible(true);

        } else if (kl.contains(k)) {
            kl.set(kl.indexOf(k.getkundennr()), k);
        }
        speichern();
    }

    /**
     * Gibt die Objekte aus der Datei in einer Kundenliste aus. Öffnet mit
     * ObjectInputStream die Liste aus der Datei und schreibt diese in die
     * Kundenliste.
     *
     * @return kl - Kundenliste
     */
    @Override
    public List anzeigen() {

        laden();

        return this.kl;
    }

    /**
     * Öffnet die Datei und schreibt die Kundenobjekte in eine Liste. Erzeugt
     * einen neuen FileInputStream auf dem angegebenen Pfad. Erzeugt einen neuen
     * ObjectInputStream auf den FileInputStream. Schreibt die gelesenen Objekte
     * aus dem ObjectInputStream in die Kundenliste. Wenn ObjectInputStream noch
     * vorhanden ist, wird dieser geschlossen.
     *
     * @param fis - FileInputStream
     * @param ois - ObjectInputStream
     * @param kl - Kundenliste
     *
     * @throws IOException, ClassNotFoundException, FileNotFoundException
     */
    public void laden() {

        FileInputStream fis = null;

        try {

            fis = new FileInputStream(kdata);

            ObjectInputStream ois = null;
            try {

                ois = new ObjectInputStream(fis);

                kl = (List<Kunde>) ois.readObject();

            } catch (IOException ioe) {
                ioe.printStackTrace();
            } catch (ClassNotFoundException cnfe) {
                cnfe.printStackTrace();
            } finally {
                try {

                    if (ois != null) {
                        ois.close();
                    }
                } catch (IOException ioe) {
                    ioe.printStackTrace();
                }
            }
        } catch (FileNotFoundException fnf) {
            fnf.printStackTrace();
        } finally {
            try {

                if (fis != null) {
                    fis.close();
                }
            } catch (IOException ioe) {
                ioe.printStackTrace();
            }
        }
    }

    /**
     * Öffnet die Datei und schreibt die Kundenliste in diese. Erzeugt einen
     * neuen FileOutputStream auf den angegebenen Pfad. Erzeugt einen neuen
     * ObjectOutputStream auf den FileOutputStream. Schreibt das Object aus der
     * Kundenliste in die Kundendatei. Wenn ObjectOutputStream noch vorhanden
     * ist, wird dieser geschlossen.
     *
     * @param fos - FileOutputStream
     * @param oos - ObjectOutputStream
     * @param kl - Kundenliste
     *
     * @throws IOException, FileNotFoundException
     */
    public void speichern() {
        FileOutputStream fos = null;
        try {

            fos = new FileOutputStream(kdata);
            ObjectOutputStream oos = null;

            try {

                oos = new ObjectOutputStream(fos);

                oos.writeObject(kl);
            } catch (IOException ioe) {

                ioe.printStackTrace();
            } finally {
                try {

                    if (oos != null) {
                        oos.close();
                    }
                } catch (IOException ioe) {

                    ioe.printStackTrace();
                }
            }
        } catch (FileNotFoundException fnf) {
            fnf.printStackTrace();
        } finally {
            try {

                if (fos != null) {
                    fos.close();
                }
            } catch (IOException ioe) {

                ioe.printStackTrace();
            }
        }
    }
}